package com.stgy.lease.web.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.stgy.lease.common.exception.StgyException;
import com.stgy.lease.common.result.ResultCodeEnum;
import com.stgy.lease.model.domain.*;
import com.stgy.lease.web.admin.dto.ApartmentInfoSaveDto;
import com.stgy.lease.web.admin.dto.ApartmentInfoSearchDto;
import com.stgy.lease.web.admin.mapper.*;
import com.stgy.lease.web.admin.service.ApartmentInfoService;
import com.stgy.lease.web.admin.service.ApartmentLabelService;
import com.stgy.lease.web.admin.vo.ApartmentDetailVo;
import com.stgy.lease.web.admin.vo.ApartmentInfoVo;
import com.stgy.lease.web.admin.vo.FeeValueVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lingx
 * @description 针对表【apartment_info(公寓信息表)】的数据库操作Service实现
 * @createDate 2024-08-28 11:00:28
 */
@Service
public class ApartmentInfoServiceImpl extends ServiceImpl<ApartmentInfoMapper, ApartmentInfo>
        implements ApartmentInfoService {

    @Autowired
    private ApartmentLabelMapper apartmentLabelMapper;
    @Autowired
    private ApartmentLabelService apartmentLabelService;

    @Autowired
    private ApartmentFacilityMapper apartmentFacilityMapper;

    @Autowired
    private DistrictInfoMapper districtInfoMapper;

    @Autowired
    private ApartmentFeeValueMapper apartmentFeeValueMapper;

    @Autowired
    private GraphInfoMapper graphInfoMapper;

    //新增或更新公寓信息
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveOrUpdateApartmentInfoSaveDto(ApartmentInfoSaveDto apartmentInfoSaveDto) {
        //1、唯一校验
        if (apartmentInfoSaveDto == null) {
            throw new StgyException(ResultCodeEnum.DATA_ERROR);
        }
        Long id = apartmentInfoSaveDto.getId();
        LambdaQueryWrapper<ApartmentInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ApartmentInfo::getDistrictId, apartmentInfoSaveDto.getDistrictId());
        wrapper.eq(ApartmentInfo::getName, apartmentInfoSaveDto.getName());
        wrapper.last("limit 1");
        ApartmentInfo one = this.getOne(wrapper);
        if (one != null && !id.equals(one.getId())) {
            throw new StgyException(ResultCodeEnum.DATA_EXISTS_ERROR);
        }

        //2、判断新增还是更新
        if (id != null) {
            //更新：先删除之前的映射缓存，保存新的映射缓存
            //多对多的映射的数据 可以使用物理删除，没有存储真实数据
            //apartment_facility 公寓id映射配套id 根据公寓id删除它的所有配套
            apartmentFacilityMapper.deleteByApartmentInfoId(id);
            //apartment_label
            apartmentLabelMapper.deleteByApartmentInfoId(id);
            //apartment_fee_value
            apartmentFeeValueMapper.deleteByApartmentInfoId(id);
            //graph_info
            graphInfoMapper.deleteByApartmentInfoId(id);
        }

        //3、保存或更新公寓信息
        ApartmentInfo apartmentInfo = new ApartmentInfo();
        BeanUtils.copyProperties(apartmentInfoSaveDto, apartmentInfo);
        //查询公寓的省市区名称设置
        //dname-》区 cname->市 pname->省
        //List 0 1 2
        Map<String, String> namesMap = districtInfoMapper.selectNamesByDid(apartmentInfoSaveDto.getDistrictId());
        apartmentInfo.setDistrictName(namesMap.get("dname"));
        apartmentInfo.setCityName(namesMap.get("cname"));
        apartmentInfo.setProvinceName(namesMap.get("pname"));
        this.saveOrUpdate(apartmentInfo);


        //4、保存公寓的映射数据
        //apartment_facility： 4     21 22 23
        //配套id集合    insert apartment_facility(apartment_id,facility_Id)
        // values(4,21),(4,22),(4,23)
        List<Long> facilityInfoIds = apartmentInfoSaveDto.getFacilityInfoIds();
        if (!CollectionUtils.isEmpty(facilityInfoIds)) {
            //重新获取id:为了获取新增后的id
            id = apartmentInfo.getId();
            apartmentFacilityMapper.insertBatchIds(id, facilityInfoIds);//自定义sql
        }

        //apartment_label
        List<ApartmentLabel> apartmentLabels = null;
        if (!CollectionUtils.isEmpty(apartmentInfoSaveDto.getLabelIds())) {
            apartmentLabels =
                    apartmentInfoSaveDto.getLabelIds().stream()
                            .map(labelInfo -> {
                                ApartmentLabel apartmentLabel = new ApartmentLabel();
                                apartmentLabel.setApartmentId(apartmentInfo.getId());
                                apartmentLabel.setLabelId(labelInfo);
                                return apartmentLabel;
                            }).collect(Collectors.toList());
            apartmentLabelService.saveBatch(apartmentLabels);
        }

        //apartment_fee_value
        List<Long> feeValueIds = apartmentInfoSaveDto.getFeeValueIds();
        if (!CollectionUtils.isEmpty(feeValueIds)) {
            //重新获取id:为了获取新增后的id
            id = apartmentInfo.getId();
            apartmentFeeValueMapper.insertBatchIds(id, feeValueIds);//自定义sql
        }

        //graph_info
        List<GraphInfo> graphInfoList = apartmentInfoSaveDto.getGraphVoList();
        if (!CollectionUtils.isEmpty(graphInfoList)) {
            //apartment_label
            for (GraphInfo graphInfo : graphInfoList) {
                graphInfo.setItemType(1);
                graphInfo.setItemId(id);
                graphInfo.setCreateTime(new Date());
                graphInfo.setUpdateTime(new Date());
            }
            graphInfoMapper.insertBatchIds(graphInfoList);
        }

        return true;
    }

    //条件分页查询公寓列表
    @Override
    public Page<ApartmentInfoVo> pageItem(ApartmentInfoSearchDto searchDto) {
        //封装分页数据
        Page<ApartmentInfoVo> page = new Page<>(searchDto.getCurrent(), searchDto.getSize());
        //使用mp支持的分页对象 自定义sql
        List<ApartmentInfoVo> list = baseMapper.selectPageItem(page, searchDto);
        //组装分页数据
        page.setRecords(list);
        return page;
    }

    //根据id删除公寓信息
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeApartmentInfoById(Long id) {
        this.removeById(id);
        apartmentLabelMapper.deleteByApartmentInfoId(id);
        apartmentFacilityMapper.deleteByApartmentInfoId(id);
        apartmentFeeValueMapper.deleteByApartmentInfoId(id);
        graphInfoMapper.deleteByApartmentInfoId(id);
        return true;
    }

    //根据ID获取公寓详细信息
    @Override
    public ApartmentDetailVo getDetailById(Long id) {
        //多步查询 或者自定义sql查询数据组装
        ApartmentInfo apartmentInfo = this.getById(id);
        if (apartmentInfo == null) {
            throw new StgyException(ResultCodeEnum.DATA_ERROR);
        }
        //label_info 公寓标签信息
        List<LabelInfo> labelInfoList =
                apartmentLabelMapper.selectLabelInfosByApartmentId(id);
        ////facility_info 公寓配套信息
        List<FacilityInfo> facilityInfoList =
                apartmentFacilityMapper.selectFacilityInfosByApartmentId(id);
        //fee_value 杂费和键
        List<FeeValueVo> feeValueVoList =
                apartmentFeeValueMapper.selectFeeValueVosByApartmentId(id);

        LambdaQueryWrapper<GraphInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(GraphInfo::getItemId, id);
        List<GraphInfo> graphInfoList = graphInfoMapper.selectList(wrapper);

        ApartmentDetailVo apartmentDetailVo = new ApartmentDetailVo();
        BeanUtils.copyProperties(apartmentInfo, apartmentDetailVo);
        apartmentDetailVo.setFacilityInfoList(facilityInfoList);
        apartmentDetailVo.setFeeValueVoList(feeValueVoList);
        apartmentDetailVo.setLabelInfoList(labelInfoList);
        apartmentDetailVo.setGraphVoList(graphInfoList);

        //自定义sql查询数据组装
        //apartment_info 根据公寓id查询
        //apartment_label 中间表
        //label_info
        //apartment_facility
        //facility_info
        //apartment_fee_value
        //fee_key
        //fee_value
        //graph_info 公寓id与它的item_id
        return apartmentDetailVo;
    }

    //根据id获取该地区的公寓列表
    @Override
    public List<ApartmentInfo> getByDistrictId(Long districtId) {
        if (districtId == null || districtId < 0) {
            throw new StgyException(ResultCodeEnum.DATA_ERROR);
        }
        LambdaQueryWrapper<ApartmentInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ApartmentInfo::getDistrictId, districtId);
        return this.list(wrapper);
    }

    //根据id更新公寓的发布状态
    @Override
    public boolean updateReleaseStatusById(Long id, Integer status) {
        if (id == null || id < 0 || status == null || status < 0) {
            throw new StgyException(ResultCodeEnum.DATA_ERROR);
        }
        LambdaQueryWrapper<ApartmentInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ApartmentInfo::getId, id);
        wrapper.last("limit 1");
        ApartmentInfo one = this.getOne(wrapper);
        one.setIsRelease(status);
        this.saveOrUpdate(one);
        return true;
    }

}




